package cn.maihe.elg.operation.schedule;

import cn.maihe.elg.operation.config.ElgConfig;
import cn.maihe.elg.operation.model.enums.InvoiceReversalFlag;
import cn.maihe.elg.operation.model.enums.InvoiceStatusEnum;
import cn.maihe.elg.operation.repository.entity.InvoiceInfoDO;
import cn.maihe.elg.operation.repository.entity.InvoiceInfoDOCondition;
import cn.maihe.elg.operation.service.invoice.InvoiceInfoService;
import cn.maihe.elg.operation.supports.invoice.nuonuo.InvoiceDownLoadHelper;
import cn.maihe.elg.operation.supports.invoice.nuonuo.InvoiceHelper;
import cn.maihe.elg.operation.utils.ElgLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.file.Path;
import java.sql.Date;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

/**
 * @Description 定时查询开票结果
 * @Author caixh
 * @Date 2021/5/7.
 */
@Slf4j
@Service
public class InvoiceResultCheckJob {
    @Resource
    private InvoiceInfoService invoiceInfoService;
    @Resource
    private InvoiceHelper invoiceHelper;
    @Resource
    private InvoiceDownLoadHelper invoiceDownLoadHelper;
    @Resource(name = "invoiceDownLoadHandleExecutor")
    private ThreadPoolTaskExecutor executor;
    @Resource
    private ElgConfig elgConfig;
    @Scheduled(cron = "${cn.maihe.elg.operation.schedule.invoiceResultQueryCron}")
    public void invoiceResultQuery() {
        LocalDateTime dt = LocalDateTime.now().minusMinutes(5);
        InvoiceInfoDOCondition downQW = InvoiceInfoDOCondition.builder()
                .andStatusEq(InvoiceStatusEnum.TODOWNLOAD.getValue())
                .andGmtCreateLe(Date.from(dt.atZone(ZoneId.systemDefault()).toInstant()))
                .andQueryTimesLe(10);
//        if(elgConfig.getEnableCenterId()!=null){
//            downQW.andCenterIdEq(elgConfig.getEnableCenterId());
//        }
        List<InvoiceInfoDO> downLoads = invoiceInfoService.selectList(downQW.build());
        downLoads.forEach(invoiceInfoDO -> {
            executor.execute(() -> {
                String acceptOrderNo = invoiceInfoDO.getAcceptOrderNos();
                try {
                    ElgLogger.info(log, l -> l.info("acceptOrderNo:{} >> 发票下载：{}", acceptOrderNo));
                    Path invoicePdf = invoiceDownLoadHelper.downloadInvoice(invoiceInfoDO.getPdfUrl());
                    ElgLogger.info(log, l -> l.info("acceptOrderNo={} << 发票下载成功：{}", acceptOrderNo, invoicePdf.toAbsolutePath().toString()));
                    invoiceDownLoadHelper.savePdfAndUpdateInvoice(invoicePdf, invoiceInfoDO);
                    invoiceInfoDO.setQueryTimes(invoiceInfoDO.getQueryTimes() + 1);
                    invoiceInfoService.updateById(invoiceInfoDO);
                } catch (Exception e) {
                    ElgLogger.error(log, l -> l.error("acceptOrderNo={} << 发票下载失败:{}", acceptOrderNo, e.getMessage(), e));
                    invoiceInfoDO.setRemark("发票下载失败：" + e.getMessage());
                    invoiceInfoDO.setQueryTimes(invoiceInfoDO.getQueryTimes() + 1);
                    invoiceInfoService.updateById(invoiceInfoDO);
                }
            });
        });


        //已发起开票申请且已申请超过5s的发起开票结果查询
        InvoiceInfoDOCondition qw = InvoiceInfoDOCondition.builder()
                .andStatusEq(InvoiceStatusEnum.PROSESS.getValue())
                .andGmtCreateLe(Date.from(dt.atZone(ZoneId.systemDefault()).toInstant().minusSeconds(5)));
//        if (elgConfig.getEnableCenterId() != null) {
//            qw.andCenterIdEq(elgConfig.getEnableCenterId());
//        }
        List<InvoiceInfoDO> invoiceInfoDOS = invoiceInfoService.selectList(qw.build());
        invoiceInfoDOS.forEach(invoice -> {
            try {
                invoiceHelper.queryInvoiceResultAndDownload(invoice);
            } catch (Exception e) {
                ElgLogger.error(log, l -> l.error("{} orderNo={} << 开票结果查询失败:{}", invoice.getAcceptOrderNos(), invoice.getId(), e.getMessage(), e));
            }
        });
    }

    @Scheduled(cron = "${cn.maihe.elg.operation.schedule.invoiceReversalCron}")
    public void doInvoiceReversalApply() {

        //已标记待冲红且已申请超过5s的蓝票记录需要发起冲红开票申请
        InvoiceInfoDOCondition qw = InvoiceInfoDOCondition.builder()
                .andStatusEq(InvoiceStatusEnum.INVOICED.getValue())
                .andInvoiceTypeEq(1)
                .andInvoiceReversalFlagEq(InvoiceReversalFlag.WAITING.getFlag())
                .andGmtCreateLe(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().minusSeconds(5)))
                .andQueryTimesLe(20);
//        if (elgConfig.getEnableCenterId() != null) {
//            qw.andCenterIdEq(elgConfig.getEnableCenterId());
//        }
        List<InvoiceInfoDO> reversalInvoices = invoiceInfoService.selectList(qw.build());
        reversalInvoices.forEach(invoice -> {
            try {
                invoiceHelper.doInvoiceReversal(invoice);
            } catch (Exception e) {
                //更新冲红失败次数
                InvoiceInfoDO updateInvoiceInfo = InvoiceInfoDO.builder().id(invoice.getId()).queryTimes(invoice.getQueryTimes() + 1).build();
                invoiceInfoService.updateById(updateInvoiceInfo);
                ElgLogger.error(log, l -> l.error("acceptOrderNo={} orderNo={} << 发票冲红申请失败:{}", invoice.getAcceptOrderNos(), invoice.getId(), e.getMessage(), e));
            }
        });
    }
}
